<?php
/**
 * Класс таблицы "actions"
 * 
 * @author naspeh
 * @version $Id: Actions.php 669 2008-06-30 10:10:44Z naspeh $
 */
class Core_Table_Actions extends Core_Table_Resource_Abstract
{
    /**
     * Имя
     *
     * @var string
     */        
    protected $_name = 'actions';
    /**
     * Связное поле
     *
     * @var string
     */      
    protected $_fieldTie = 'action_id';
    /**
     * Зависимые таблицы
     *
     * @var array
     */    
    protected $_dependentTables = array();
    /**
     * Карта связей
     *
     * @var array
     */      
    protected $_referenceMap    = array(
        'Resource' => array(
            'columns'           => array('id'),
            'refTableClass'     => 'Core_Table_Resources',
            'refColumns'        => 'action_id',
        )
    );
    /**
     * Выбрать по url
     *
     * @param string $url
     * @return array
     */
    public static function fetchByUrl ($urlQuery)
    {
        if ('' == $urlQuery) {
            $urlQuery = 'index/index';
        }
        $url = trim((string) $urlQuery, '/\\');
        $tableActions = new Core_Table_Actions();
        if(null !== ($row = $tableActions->fetchRow(array('url_alias = ?' => $url)))) {
            return $row->toArray();
        }
        $url = split('/', $url);
        $url = array_diff($url, array(''));
        $url = array_values($url);
        $select = Core_Db::getInstance()->select();
        $count = count($url);
        if (0==$count) {
            return false;
//        	throw new Core_Exception('emptyUrl# ' . $urlQuery);
        }
        if (0<$count) {
            $select->from(array('a1' => 'actions'))
                   ->where('a1.name = ?', $url[0])
                   ->where('a1.parent is null');
        }
        if (1<$count) {
            $select->join((array('a2' => 'actions')), 'a2.parent = a1.id')
                   ->where('a2.name = ?', $url[1]);
        }
        if (2<$count) {
            $select->join((array('a3' => 'actions')), 'a3.parent = a2.id')
                   ->where('a3.name = ?', $url[2]);
        
        }
        $select->limit(1);
        if (false === ($row = current($select->query()->fetchAll()))) {
            if (Core_Loader::MODULE_DEFAULT !== $url[0]) {
                $row = self::fetchByUrl(Core_Loader::MODULE_DEFAULT . '/' . trim($urlQuery, '/\\'));
            } else {
                return false;
//            	throw new Core_Exception('badUrl# ' . $urlQuery);
            }
        }
        return $row;
    }
    /**
     * Обновить все действия
     *
     * @return Core_Table_Actions
     */
    public function updateAll ()
    {
        $resultIds = array();
        $chain = new Zend_Filter();
        $chain->addFilter(new Zend_Filter_Word_CamelCaseToDash());
        $chain->addFilter(new Zend_Filter_StringToLower()); 
        foreach (Core_Loader::getModuleToPath() as $module => $path) {
            $where = array('parent is NULL' , 'name = ?' => $module);
            if (null === ($resultModule = $this->fetchRow($where))) {
                $resultModule = $this->fetchNew();
                $resultModule->name = $module;
                $resultModule->desc = $module;
                $resultModule->url_alias = $module;
                $resultModule = $resultModule->save();
            } else {
                $resultModule = $resultModule->id;
            }
            $resultIds[] = $resultModule;
            $path .= Core_Loader::SUFFIX_CONTROLLERS;
            foreach (scandir($path) as $filename) {
                if (preg_match('/Controller\.php$/', $filename)) {
                    $controllerName = preg_replace('/Controller\.php$/', '', $filename);
                    $className = $controllerName . 'Controller';
                    if (Core_Loader::MODULE_DEFAULT != $module) {
                        $className = $module . '_' . $className;
                    }
                    $controller = $chain->filter($controllerName);
                    $where = array('parent = ?' => $resultModule , 'name = ?' => $controller);
                    if (null === $resultController = $this->fetchRow($where)) {
                        $resultController = $this->fetchNew();
                        $resultController->parent = $resultModule;
                        $resultController->name = $controller;
                        $resultController->desc = $controllerName;
                        $resultController->url_alias = $module . '/' . $controller;
                        $resultController = $resultController->save();
                    } else {
                        $resultController = $resultController->id;
                    }
                    $resultIds[] = $resultController;
                    require_once ($path . DIRECTORY_SEPARATOR . $filename);
                    $methods = get_class_methods($className);
                    foreach ((array) $methods as $method) {
                        if (preg_match('/(\w+)Action$/', $method, $matches)) {
                            $action = $matches[1];
                            $action = $chain->filter($action);
                            $where = array('parent = ?' => $resultController , 'name = ?' => $action);
                            if (null === $resultAction = $this->fetchRow($where)) {
                                $resultAction = $this->fetchNew();
                                $resultAction->parent = $resultController;
                                $resultAction->name = $action;
                                $resultAction->desc = $action;
                                $resultAction->url_alias = implode('/', array($module, $controller, $action));
                                $resultAction = $resultAction->save();
                            } else {
                                $resultAction = $resultAction->id;
                            }
                            $resultIds[] = $resultAction;
                        }
                    }
                }
            }
        }
        $this->delete(array('id not in (?)' => array($resultIds)));
        return $this;
    }
}